package com.changpei.core.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.changpei.common.cache.CategoryCache;
import com.changpei.common.cache.RedisUtil;
import com.changpei.common.result.Result;
import com.changpei.core.pojo.Category;
import com.changpei.core.service.CategoryService;
import com.changpei.core.utils.SearchUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>Title : Category</p>
 * <p>Description : category的控制层</p>
 *
 * @author weibiao
 * @date 2020年3月7日
 */

@RestController
@RequestMapping("/category")
@CrossOrigin
public class CategoryController {

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private CategoryCache categoryCache;

    @Autowired
    private RedisUtil redisUtil;

    /**
     * <p>Title : add</p>
     * <p>Description : 新增Category数据</p>
     *
     * @param category
     * @return
     */
    @PostMapping(value = "/add")
    public Result<Long> add(@RequestBody Category category) {
        // 调用CategoryService实现添加Category
        if (categoryService.save(category)) {
            return Result.ok(category.getId());
        }
        return Result.failed();
    }

    /**
     * <p>Title : delete</p>
     * <p>Description : Category根据ID数据</p>
     *
     * @param id
     * @return
     */
    @DeleteMapping(value = "/{id}")
    public Result<String> delete(@PathVariable Long id) {
        // 调用CategoryService实现根据主键删除
        if (categoryService.removeById(id)) {
            return Result.ok();
        }
        return Result.failed();
    }

    /**
     * <p>Title : update</p>
     * <p>Description : Category根据ID修改</p>
     *
     * @param category
     * @param id
     * @return
     */
    @PutMapping(value = "/{id}")
    public Result<String> update(@RequestBody Category category, @PathVariable Long id) {
        // 设置主键值
        category.setId(id);
        // 调用CategoryService实现修改Category
        if (categoryService.updateById(category)) {
            return Result.ok();
        }
        return Result.failed();
    }

    /**
     * <p>Title : findPage</p>
     * <p>Description : Category分页搜索实现</p>
     *
     * @param pageNum  : 当前页
     * @param pageSize : 每页显示多少条
     * @return
     */
    @GetMapping(value = "/search/{pageNum}/{pageSize}")
    public Result<Page<Category>> findPage(@PathVariable int pageNum, @PathVariable int pageSize) {
        // 调用CategoryService实现分页查询Category
        Page<Category> pageInfo = categoryService.page(new Page<>(pageNum, pageSize));
        return Result.ok(pageInfo);
    }

    /**
     * <p>Title : findPage</p>
     * <p>Description : Category分页条件搜索实现</p>
     *
     * @param category
     * @param pageNum  : 当前页
     * @param pageSize : 每页显示多少条
     * @return
     */
    @PostMapping(value = "/search/{pageNum}/{pageSize}")
    public Result<Page<Category>> findPage(@RequestBody(required = false) Category category, @PathVariable int pageNum, @PathVariable int pageSize) {
        // 调用CategoryService实现分页条件查询Category
        Page<Category> pageInfo = categoryService.page(new Page<>(pageNum, pageSize), SearchUtil.initQuery(category));
        return Result.ok(pageInfo);
    }

    /**
     * <p>Title : findList</p>
     * <p>Description : 多条件搜索Category数据</p>
     *
     * @param category
     * @return
     */
    @PostMapping(value = "/search")
    public Result<List<Category>> findList(@RequestBody(required = false) Category category) {
        // 调用CategoryService实现条件查询Category
        List<Category> list = categoryService.list(SearchUtil.initQuery(category));
        return Result.ok(list);
    }

    /**
     * <p>Title : findById</p>
     * <p>Description : 根据ID查询Category数据</p>
     *
     * @param id
     * @return
     */
    @GetMapping(value = "/{id}")
    public Result<Category> findById(@PathVariable Long id) {
        // 调用CategoryService实现根据主键查询Category
        Category category = categoryService.getById(id);
        return Result.ok(category);
    }

    /**
     * <p>Title : findOne</p>
     * <p>Description : 多条件搜索Category数据，结果返回一条</p>
     *
     * @param category
     * @return
     */
    @PostMapping(value = "/findOne")
    public Result<Category> findOne(@RequestBody(required = false) Category category) {
        // 调用CategoryService实现条件查询Category
        Category categoryResult = categoryService.getOne(SearchUtil.initQuery(category));
        return Result.ok(categoryResult);
    }

    /**
     * <p>Title : findAll</p>
     * <p>Description : 查询Category全部数据</p>
     *
     * @return
     */
    @GetMapping(value = "/all")
    public Result<List<Category>> findAll() {
        // 调用CategoryService实现查询所有Category
        List<Category> list = categoryService.list();
        return Result.ok(list);
    }

    /**
     * 缓存中查询
     * @return
     */
    @GetMapping(value = "/categories")
    public Result<List<JSONObject>> getCategory() {
        Set<Object> set = categoryCache.getCategory();
        if (ObjectUtils.isEmpty(set)) {
            List<Category> categories = categoryService.list();
            List<JSONObject> collect = categories.stream().map(category -> {
                JSONObject jsonObject = new JSONObject();
                jsonObject.put("key", String.valueOf(category.getId()));
                jsonObject.put("tabName", category.getName());
                return jsonObject;
            }).collect(Collectors.toList());
            collect.forEach(jsonObject -> redisUtil.sSet("category", jsonObject));
            return Result.ok(collect);
        }
        List<JSONObject> list = categoryCache.getCategory()
                .stream()
                .map(o -> JSONObject.parseObject(JSON.toJSONString(o)))
                .sorted(Comparator.comparing(a -> a.getInteger("key")))
                .collect(Collectors.toList());
        return Result.ok(list);
    }
}
